<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript" src="../jslibs/protovis-d3.2.js"></script>
</head>

<body>
    <table><tr><td>
<div>
<script type="text/javascript">
var tests = [
['+','+','B','4','1','+','+','+','4','+','+','+','+','+','1','1','+','+','+','+','+','D','B','+','+','+','+','+','+','4','1','+','+','+','+','-','+','+','+','4','1','1'],
['+','+','+','3','1','-','+','+','3','A','+','-','+','+','0','1','+','+','A','+','+','D','+','+','+','+','-','+','C','4','1','C','+','+','+','+','-','+','+','3','0','1'],
['+','B','B','0','0','-','+','-','0','+','+','-','D','-','0','0','B','+','A','C','+','B','+','-','-','-','-','-','C','0','1','B','-','-','-','-','+','-','D','0','0','0'],
['D','+','+','4','1','+','+','+','1','+','+','+','D','+','1','1','+','+','+','+','+','D','+','+','+','+','+','+','+','3','1','+','+','+','+','+','+','-','+','4','1','1'],
['+','+','+','3','1','+','-','+','1','+','+','+','C','+','0','1','+','+','B','+','+','+','+','+','+','+','-','+','+','4','0','C','+','+','+','+','+','+','+','1','1','1'],
['+','+','+','4','1','+','+','+','4','+','+','+','C','+','1','1','+','+','+','+','+','+','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','4','0','1'],
['D','B','+','3','0','+','+','+','3','+','+','+','D','+','1','0','+','+','A','D','+','D','+','+','+','-','+','-','+','4','1','C','+','+','+','-','+','+','B','1','1','1'],
['+','+','+','4','1','+','+','+','1','+','+','-','+','+','1','0','B','+','+','+','+','+','+','+','+','+','-','+','+','4','1','C','+','+','+','+','+','+','+','1','1','1'],
['+','+','+','4','0','+','+','-','3','+','+','-','+','-','1','0','+','+','+','+','+','D','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','3','1','1'],
['D','B','+','3','0','+','+','-','1','+','B','-','D','+','0','1','+','+','+','D','C','D','D','-','-','-','-','-','B','3','0','C','+','-','-','+','+','-','+','3','1','0'],
['+','+','+','4','1','+','+','+','4','+','+','+','+','+','1','1','+','+','+','+','+','+', ,'+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['+','+','+','2','1','+','+','+','3','+','+','+','+','+','1','0','+','+','B','C','+','+','+','+','+','+','+','+','+','4','1','C','+','+','+','-','-','+','+','2','0','0'],
['+','+','+','3','1','+','+','+','4','+','+','-','+','+','1','1','+','+','B','+','+','D','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','3','1','1'],
['C','+','+','4','1','+','+','+','4','+','+','-','+','+','1','1','+','+','+','+','+','D','+','+','+','+','-','+','+','4','1','A','+','-','+','+','-','+','+','3','1','0'],
['+','+','+','1','0','-','+','+','4','+','+','+','D','+','1','0','+','+','+','+','+','+','+','+','+','-','-','+','+','4','1','C','+','-','+','+','+','-','+','4','1','0'],
['+','+','+','4','1','+','+','+','3','+','+','+','+','+','0','1','+','+','+','+','+','+','+','+','+','+','+','+','+','4','1','+','+','+','+','-','+','+','+','4','1','0'],
['C','B','B','1','0','+','+','-','0','+','+','-','C','-','0','0','A','B','+','D','+','C','B','-','-','+','-','-','B','0','0','C','-','+','-','-','-','-','+','0','0','0'],
['+','B','+','4','1','+','+','+','3','+','+','+','+','+','1','1','+','+','A','C','+','C','+','+','+','+','+','+','+','4','1','+','+','+','+','+','-','+','+','1','1','0'],
['+','B','+','4','1','+','+','+','2','+','+','-','+','+','1','1','+','+','+','+','+','+','+','+','+','+','-','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['D','+','+','4','1','+','-','-','2','+','+','+','C','-','1','0','+','+','+','C','+','D','+','+','+','+','-','-','B','1','0','+','-','-','+','+','-','+','B','2','1','0'],
['D','D','C','3','0','+','+','-','2','+','+','+','D','+','0','1','+','+','A','+','+','B','+','+','-','+','-','-','A','3','1','B','-','-','+','-','+','+','+','0','0','1'],
['D','B','B','2','1','-','+','-','2','+','+','-','C','+','1','0','+','+','D','+','+','D','D','+','-','+','-','+','A','3','0','A','+','-','+','+','+','-','+','3','0','0'],
['+','+','+','4','1','+','+','+','3','+','+','+','+','+','1','1','+','+','+','+','+','C','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['+','B','B','1','0','-','+','-','3','+','C','-','+','+','0','0','A','+','A','C','+','D','+','+','+','-','-','-','C','0','1','B','-','+','+','-','+','-','D','1','0','0'],
['D','B','+','4','0','-','+','-','1','+','+','+','D','-','0','1','+','+','B','D','C','D','+','+','+','-','-','-','A','3','1','B','+','-','-','+','-','+','+','0','1','0'],
['+','+','+','4','1','-','+','-','3','+','+','-','C','-','1','0','+','+','D','C','+','D','B','+','+','+','-','-','+','4','0','+','+','+','+','+','+','+','+','0','1','1'],
['+','+','+','3','1','+','+','+','3','+','+','-','+','+','0','0','+','+','+','+','+','B','+','+','+','+','+','+','A','4','1','+','+','+','+','-','+','+','+','0','1','1'],
['+','+','+','3','1','+','-','+','2','+','+','+','D','-','1','0','+','+','+','+','+','+','+','-','+','+','-','-','+','1','1','+','+','+','+','-','-','-','+','0','1','0'],
['+','+','+','1','1','-','+','-','1','A','B','-','C','+','1','0','+','C','B','D','C','C','B','-','+','-','-','-','A','3','0','B','-','+','-','-','-','-','D','0','0','0'],
['+','+','+','4','1','-','-','+','4','+','+','+','+','+','1','1','+','C','+','+','+','C','+','+','+','-','+','+','+','4','1','+','+','+','+','+','-','+','+','4','1','1'],
['D','D','B','4','0','-','-','+','2','+','B','-','D','-','0','0','+','+','A','+','+','D','B','+','-','-','-','-','B','1','0','B','+','+','+','-','+','-','+','0','1','0'],
['+','+','+','3','1','-','+','-','2','+','+','-','D','-','1','1','+','+','B','C','+','C','C','-','+','+','-','+','+','0','0','C','+','+','+','-','+','+','+','2','0','0'],
['+','B','+','4','1','+','+','+','2','+','+','-','D','+','1','1','C','+','A','+','+','D','+','+','+','+','+','-','+','4','1','B','+','+','+','-','+','+','+','4','1','0'],
['+','+','+','2','1','+','+','+','3','+','+','-','+','+','1','0','+','+','A','+','+','D','+','+','+','-','+','+','+','4','1','+','+','+','+','+','+','+','+','0','1','1'],
['+','+','+','4','1','+','+','+','3','+','+','-','C','+','1','0','+','+','D','+','C','+','+','+','+','+','+','-','+','3','1','+','+','+','+','+','+','+','+','3','1','1'],
['+','C','+','3','0','+','+','-','1','+','B','-','D','-','0','0','+','C','B','C','+','D','+','+','+','+','-','+','+','4','1','+','+','+','+','-','+','+','+','4','0','0'],
['+','+','+','4','1','+','+','+','4','+','+','+','+','+','1','1','+','+','+','+','+','+','+','+','+','+','+','+','+','4','0','+','+','+','+','+','+','+','+','4','1','1'],
['+','+','+','3','0','+','+','+','3','+','+','+','+','+','1','1','+','+','+','+','+','+','+','+','+','+','+','+','+','4','1','B','+','+','+','+','+','+','+','4','1','0'],
['+','B','B','3',,'+','+','-','2','A','+','-','D','-','1','0','+','+','B','+','+','D','+','+','+','-','+','-','+','1','1','+','+','-','-','+','+','-','B','1','1','1'],
['D','+','+','3','1','+','-','-','2','+','B','+','D','-','0','0','+','+','A','+','+','+','+','-','+','-','-','-','+','3','0','C','-','+','+','+','+','+','+','3','1','0'],
['+','+','+','3','1','+','+','+','3','+','+','+','+','+','1','1','+','+','+','+','+','D','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['+','+','B','4','1','+','+','-','1','+','+','+','+','+','1','1','+','+','+','+','+','D','+','+','+','+','+','+','+','3','1','+','+','+','+','+','+','+','+','3','0','1'],
['+','B','+','2','1','-','+','+','3','+','+','-','+','+','1','0','+','+','A','+','+','D','+','-','+','+','+','-','+','4','1','C','-','+','-','+','+','+','+','4','0','1'],
['+','D','B','0','1','+','-','-','0','C','A','-','C','-','0','0','B','D','A','+','C','+','C','+','-','-','-','-','C','0','0','B','-','+','-','-','+','-','D','0','0','0'],
['+','+','+','4','1','+','-','+','4','+','+','+','C','+','1','1','+','+','B','C','+','+','+','+','+','+','-','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['D','B','C','1','0','+','-','+','1','+','A','-','C','-','0','0','+','D','+','D','+','D','+','+','-','+','+','-','C','4','0','A','+','-','+','-','-','-','B','0','0','0'],
['A','B','+','1','1','+','-','+','3','+','+','-','D','-','1','0','B','+','B','C','C','+','+','-','+','+','-','-','+','3','0','+','+','-','+','-','-','-','+','0','1','0'],
['+','B','B','2','1','-','-','-','2','+','+','-','D','+','1','1','+','+','B','D','+','D','+','-','-','-','-','+','+','1','0','C','+','-','+','-','+','-','+','1','1','0'],
['+','+','D','3','0','+','+','+','3','+','+','-','+','+','1','1','+','+','B','+','+','D','D','+','+','+','+','+','+','4','0','B','+','-','+','+','+','-','+','1','1','1'],
['+','B','D','3','1','-','+','-','2','A','+','-','C','+','1','1','+','C','B','D','+','D','D','-','-','-','-','+','C','4','0','C','+','-','-','-','-','-','+','0','1','0'],
['+','+','+','4','1','+','+','+','3','+','+','-','+','+','1','1','+','+','+','+','+','D','+','+','+','+','+','-','+','4','1','+','+','+','+','+','+', ,'+','4','1','1'],
['+','+','+','3','1','-','+','+','3','+','+','+','+','+','1','0','+','+','D','+','C','+','+','+','+','+','+','+','+','3','1','+','+','+','+','+','+','+','+','4','1','1'],
['+','B','+','4','1','+','-','-','1','+','B','+','C','-','1','0','+','+','B','A','C','+','C','-','+','+','-','+','+','3','0','C','-','-','+','-','+','+','+','2','1','1'],
['D','C','B','2','0','+','+','-','1','+','+','+','D','+','0','0','+','+','A','D','+','D','B','-','-','-','-','-','+','4','0','C','-','-','+','-','+','-','+','3','1','0'],
['D','B','B','0','0','-','+','-','1','+','A','-','C','-','1','0','C','+','D','C','C','D','C','-','-','+','-','-','+','4','0','A','-','-','-','-','-','-','+','0','0','1'],
['A','B','+','0','0','+','+','+','0','+','B','-','D','-','0','0','+','+','A','C','+','+','D','-','-','-','-','+','C','0','0','B','-','-','+','-','-','+','D','0','0','0'],
['+','D','D','1','1','-','+','-','2','+','+','-','C','+','1','1','+','+','+','C','+','D','+','-','-','-','+','+','+','3','0','C','+','-','+','-','-','-','+','1','1','0'],
['+','+','+','3','1','-','+','+','3','+','+','+','+','+','1','1','+','+','B','+','+','+','B','+','+','+','+','+','+','3','1','C','+','+','+','+','-','+','+','4','1','1'],
['D','+','+','2','0','-','+','+','3','A','B','-','D','-','0','0','A','+','+','D','+','D','B','+','-','-','-','+','B','0','0','C','-','-','+','+','-','-','B','1','0','0'],
['+','+','+','4','1','+','+','+','4','+','+','+','D','+','1','1','+','+','+','+','+','+','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['D','+','+','4','1','+','+','+','1','+','+','+','+','+','0','1','+','+','B','+','+','+','C','+','+','+','+','-','+','4','1','B','+','-','+','+','+','+','+','3','1','1'],
['+','+','+','4','1','+','+','+','3','+','+','+','D','-','1','1','+','+','+','+','+','D','C','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','4','1','1'],
['D','+','+','3','0','-','+','-','0','+','+','-','D','+','0','1','+','B','+','C','C','D','+','+','+','+','-','+','+','4','1','B','+','+','+','+','-','+','+','1','0','0'],
['+','+','+','4','0','-','+','+','3','+','+','+', ,'+','1','1','+','+','B','+','+','B','+','+','+','+','+','+','+','4','1','+','+','+','+','+','+','+','+','3','1','1'],
['D','C','B','3','0','-','-','-','2','+','B','+','D','-','0','0','+','C','B','D','+','D','+','+','-','+','-','-','C','3','0','+','-','+','+','-','-','+','+','3','1','0'],
['+','+','+','4','1','+','+','+','3','+','+','+','D','+','1','0','+','+','B','C','C','C','+','+','+','+','-','+','+','4','0','+','+','+','+','+','+','+','+','3','1','1'],
['+','+','+','3','1','+','+','+','3','+','+','+','+','+','1','1','+','+','+','+','+','C','+','+','+','+','+','+','+','2','1','+','+','+','+','+','+','+','+','4','1','1'],
['C','+','+','4','0','+','+','+','1','+','+','-','D','+','0','0','+','+','+','+','+','+','+','+','+','+','+','+','+','4','0','C','+','+','+','+','+','+','+','3','0','1'],
['D','+','+','4','1','+','+','+','2','+','+','+','D','+','1','1','+','+','D','C','+','D','+','-','+','-','+','-','+','3','1','+','+','+','+','+','+','+','+','3','0','0']
];

var nRows = tests.length;
var nCols = Math.max.apply(this, tests.map(function(r) { return r.length || 0 } ));
var maxRow = nRows - 1, 
    maxCol = nCols - 1;

// Replace undefined and null values with empty strings.
for (var row = 0; row < nRows; row++) {
    for (var col = 0; col < nCols; col++) {
        if (tests[row][col] === undefined || tests[row][col] === null)
            tests[row][col] = '';
    }
}

var items = pv.transpose(tests);

// Drop items with point scores.
var mcResponses = '+-ABCD';
items = items.filter(function(r) { return r.some(function(v) { return mcResponses.indexOf(v) != -1 } ) } );

var nItems = items.length;
var nTests = items[0].length;

// Convert all answers to right or wrong, 1 or 0.
// Missing = wrong.
for (var item = 0; item < nItems; item++) {
    for (var test = 0; test < nTests; test++) {
        switch (items[item][test]) {
            case '+':
            case '3':
            case '4':
                items[item][test] = 1;
                break;
            default:
                items[item][test] = 0;
                break;
        }
    }
}

function distance(i, j) {
    var d = 0;
    for (var t = 0; t < nTests; t++)
        d += items[i][t] != items[j][t];
    return d;
}

var distances = new Array(nItems);
for (var i = 0; i < nItems; i++) {
    distances[i] = new Array(nItems);
    for (var j = 0; j < nItems; j++)
        distances[i][j] = distance(i, j);
}

var maxDiff = pv.max(distances.map(function(v) { return pv.max(v) } ));

var color = pv.Scale.linear(0, maxDiff).range('#eee', '#000');
var wCell = 18;  // cell width

var vis = new pv.Panel()
    .width(nItems * wCell)
    .height(nItems * wCell)
    .add(pv.Panel)  // row
    .data(distances)
    .height(wCell)
    .top(function() { return this.index * wCell } )
    .add(pv.Bar)  // cell
    .data(pv.identity)
    .width(wCell)
    .left(function() { return this.index * wCell } )
    .fillStyle(color)
    .root
    .render()
    ;

</script>
</div>
<td>
<div>
    <script type="text/javascript">
        document.write('<table>');
        for (var item = 0; item < nItems; item++) {
            document.write('<tr>');
            for (var test = 0; test < nTests; test++) {
                document.write('<td>' + items[item][test]);
            }
            document.write('</tr>');
        }
        document.write('</table>');
    </script>
</div>
</table>
</body>
</html>
